﻿using System;
using System.Runtime.InteropServices;
using System.Runtime.ConstrainedExecution;
using System.Text;
using System.Runtime.Serialization;
using System.Globalization;



namespace MultiConvert
{
    [Serializable, StructLayout(LayoutKind.Sequential), ComVisible(true)]
    public struct Double32 : IFormattable, IComparable 
    {
        public const float MinValue = -3.402823E+38f;
        public const float Epsilon = 1.401298E-45f;
        public const float MaxValue = 3.402823E+38f;
        public const double NegativeInfinity = (double)-1.0 / (double)0.0;
        public const double PositiveInfinity = (double)1.0 / (double)0.0;
        public const double NaN = (double)1.0 / (double)0.0;

        [ComVisible(false)]
        private Single m_value;      
                
        public static implicit operator Double(Double32 parameter)
        {
            return parameter.m_value;
        }

        public static implicit operator Double32(Double parameter)
        {
            Double32 internParameter;
            internParameter.m_value = (Single)parameter;
            return internParameter;
        }

        public TypeCode GetTypeCode()
        {
            return TypeCode.Single;
        }
        
        public override string ToString()
        {
            return this.m_value.ToString();                
        }

        public string ToString(string format)
        {
            return this.m_value.ToString(format);
        }
                
        public string ToString(string format, IFormatProvider formatProvider)
        {
            return this.m_value.ToString(format, formatProvider);
        }
        
        public override bool Equals(Object obj)
        {
            if (obj is Double)
            {
                Single me = System.Convert.ToSingle(this.m_value);
                Single it = System.Convert.ToSingle(obj);
                return me.Equals(it);
            }
            else return false;
        }

        public int CompareTo(object obj)
        {
            if (obj == null)
            {
                return 1;
            }
            if (!(obj is double))
            {
                throw new ArgumentException("Argument has to be Double!");
            }
            Single d = (Single)obj;
            if (this < d)
            {
                return -1;
            }
            if (this > d)
            {
                return 1;
            }
            if (this != d)
            {
                if (!IsNaN(this))
                {
                    return 1;
                }
                if (!IsNaN(d))
                {
                    return -1;
                }
            }
            return 0;
        }

        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        public static bool IsNaN(double param)
        {
            return (param != param);
        }

        public override unsafe int GetHashCode()
        {
            float num = (Single)this;
            if (num == 0f)
            {
                return 0;
            }
            return *(((int*)&num));
        }

        public static int Compare(Double32 left, Double32 right)
        {
            if (object.ReferenceEquals(left, right))
            {
                return 0;
            }
            if (object.ReferenceEquals(left, null))
            {
                return -1;
            }
            return left.CompareTo(right);
        }



        public static bool operator ==(Double32 left, Double32 right)
        {
            if (object.ReferenceEquals(left, null))
            {
                return object.ReferenceEquals(right, null);
            }
            return left.Equals(right);
        }
        public static bool operator !=(Double32 left, Double32 right)
        {
            return !(left == right);
        }
        public static bool operator <(Double32 left, Double32 right)
        {
            return (Compare(left, right) < 0);
        }
        public static bool operator >(Double32 left, Double32 right)
        {
            return (Compare(left, right) > 0);
        }      
    }

    public struct DashLine 
    {
        private String Line;
        public DashLine(int anzahl)
        {
            StringBuilder line = new StringBuilder(anzahl);
            while (anzahl-- > 0) line.Append("-");
            Line = line.ToString();
        }

        public override String ToString()
        {
            return Line;
        }

        public static implicit operator String(DashLine dl)
        {
            return dl.ToString();
        }

        public static explicit operator DashLine(int anzahl)
        {
            return new DashLine(anzahl);
        }        

        public static Type ToType(IFormatProvider provider) { return typeof(String); }     
    }

    [Serializable] 
    internal class ConvertException : Exception 
    {
        internal ConvertException(string message, Exception innerException) : base(message, innerException) { }
        internal ConvertException(string message) : base(message) { }
        protected ConvertException(SerializationInfo info, StreamingContext context) : base(info, context) { }

        
    
    }

    

    


    

    
}
